package com.genius.util.Utils.HTTP;

import com.genius.util.Atom.superMan;
import com.genius.util.ConstPool.illuminatorPool;
import org.apache.commons.fileupload.FileItem;
import org.springframework.util.DigestUtils;

import java.io.*;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class FileSuperMan implements superMan {

    /** Operation File**/
    public static boolean createDirectory(String src){
        if(src==null||src.equals("")){
            return false;
        }else{
            File file = new File(src);
            if(!file.exists()){
                return file.mkdir();
            }
            return false;
        }
    }

    public static boolean createFile(String src){
        if(src==null||src.equals("")){
            return false;
        }else{
            File file = new File(src);
            if(!file.exists()&&!file.isDirectory()){
                return file.mkdir();
            }
            return false;
        }
    }

    private static boolean deleteFile(File file){
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                deleteFile(f);
            } else {
                if(!f.delete()){
                    return false;
                }
            }
        }
        //文件夹删除
        return file.delete();
    }

    public static boolean deleteFile(String src){
        if(src==null||src.equals("")||src.toUpperCase().charAt(0)=='C'){
            return false;
        }
        File file = new File(src);
        return deleteFile(file);
    }

    public static File getDirectory(String src){
        if(src==null||src.equals("")) {
            return null;
        }
        File file = new File(src);
        if(file.isDirectory()){
            return file;
        }
        return null;
    }



    /** File Info Module **/
    public static String getFileType(String src){
        File file = new File(src);
        return getFileType(file);
    }


    public static String getFileType(File file){
        if(!file.exists()&&!file.isDirectory()){
            return null;
        }
        else{
            String fileName = file.getName();
            String temp=URLConnection.guessContentTypeFromName(fileName);
            if(temp==null){
                String split[] = fileName.split("\\.");
                if(split.length>1){
                    return split[split.length-1];
                }else{
                    return null;
                }
            }else{
                return temp;
            }
        }
    }

    public static long getFileSize(String src){
        File file = new File(src);
        return getFileSize(file);

    }

    public static long getFileSize(File file){
        if(!file.exists()&&!file.isDirectory()){
            return -1;
        }
        else{
            return file.length();
        }
    }



    /** Read And Write Moudle **/
    public static byte[] readFileByByte(InputStream inputStream,long byteSize){
        if(byteSize>Integer.MAX_VALUE||byteSize<=0){
            byteSize = illuminatorPool.uploadFileMd5Size;
        }
        byte buffer[] = new byte[(int)byteSize];
        try (InputStream temp = inputStream){
            if(temp.read(buffer)!=-1){
                return buffer;
            }
            inputStream.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer;
    }

    //通过scanner读取数据，读取一行销毁一行，减少文件流在内存中堆积
    public static void readFile(String sourceUrl,String targetUrl){
        char[] cache = new char[4096];
        try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(sourceUrl), StandardCharsets.UTF_8));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetUrl),StandardCharsets.UTF_8))) {
            int len = -1;
            while((len=br.read(cache))!=-1){
                writer.write(cache,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //可供自己管理的文件读取 禁用
    public static void readFile0(String sourceUrl,String targetUrl)throws IOException{
        FileReader fileReader = new FileReader(sourceUrl);
        FileWriter fileWriter = new FileWriter(targetUrl);
        StringBuffer s = null;
        int MaxBufferCache = 8092;
        int MaxLineLength = 128;

        int nlines = 0;
        int nChar = 0;
        int startChar = 0;
        int nextChar  = 0;
        boolean eof = false;
        char c = 0;
        char[] buffer = new char[MaxBufferCache+1];
        String str = null;

        while(true){
            if(nextChar>=nChar){
                int n = fileReader.read(buffer,0,MaxBufferCache);
                if(nChar==-1)break;
                nChar = n;
                nextChar = 0;
                startChar = 0;
            }
            int i = 0;
            for(i=startChar;i<nChar;i++){
                c = buffer[i];
                if(c=='\n'||c=='\r'){
                    eof = true;
                    break;
                }
            }
            nextChar = i;
            int len = nextChar - startChar;
            if(eof){
                nextChar++;
                if(s == null){
                    str = new String(buffer,startChar,len);
                }
                else{
                    s.append(buffer,startChar,len);
                    str = s.toString();
                    s = null;
                }
            }
            fileWriter.write(str);
            fileWriter.write(new char[]{'\r','\n'});
            if(c=='\r'){
                if(nextChar>=nChar){
                    int n = fileReader.read(buffer,0,MaxBufferCache);
                    if(nChar==-1)break;
                    nChar = n;
                    nextChar = 0;
                }
            }
            if(nextChar<nChar&&buffer[nextChar]=='\n'){
                nextChar++;
            }
            if (s == null)
                s = new StringBuffer(MaxLineLength);
            s.append(buffer,startChar,len);
            startChar = nextChar;
        }
        fileWriter.close();
        fileReader.close();

    }


    public static void writeFileByBuffereReader(InputStream in, String filename){
        try (BufferedReader buffer = new BufferedReader(new InputStreamReader(in,"UTF-8"));
             FileOutputStream out = new FileOutputStream(illuminatorPool.uploadFileSavePath+"\\"+filename);
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out,"UTF-8"));){
            String line;
            while((line=buffer.readLine())!=null){
                writer.write(line);
                writer.newLine();
            }
            in.close();
        }catch (IOException e){
           e.printStackTrace();
        }
    }

    public static String writeFileByInputStream(InputStream in,String src){
        String savePath = src;
        try (FileOutputStream out = new FileOutputStream(savePath);InputStream tempIn = in){
            byte buffer[] = new byte[4096];
            int len = 0;
            while((len=tempIn.read(buffer))>0){
                out.write(buffer,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return savePath;
    }

    public static File webUploadFile(List<FileItem> list,String md5) throws IOException{
        File uploadFile = null;
        for(FileItem item:list){
            if(!item.isFormField()){
                String filename = item.getName();
                if(filename==null||filename.trim().equals("")){
                    continue;
                }

                filename = filename.substring(filename.lastIndexOf("\\")+1);
                uploadFile = new File(writeFileByInputStream(item.getInputStream(),illuminatorPool.uploadFileSavePath+md5+"_"+filename));
            }
        }
        return uploadFile;
    }

    /** Big File Module **/
    public static File webUploadBigFile(FileItem item, int slice, int length,String md5,String fileName)throws IOException{
        String path = illuminatorPool.uploadFileTempPath+length+"_"+md5+"\\";
        if(fileName==null||fileName.trim().equals("")){
            return null;
        }
        String temp[] = fileName.split("\\.");
        String type = temp.length<1?"bin":temp[temp.length-1];
        String tempName = slice+"_"+ md5 +"."+type;
        File tempFile = new File(path+tempName);
        if(tempFile.exists()){
            return tempFile;
        }
        File uploadFile = null;
        if(!item.isFormField()){
            InputStream inputStream = item.getInputStream();
            uploadFile = new File(writeFileByInputStream(inputStream,path+tempName));
        }
        return uploadFile;
    }

    public static File mergeFiles(String path,String fileName,String md5,int length){
        File rootFile = new File(path);
        List<File> files = new ArrayList<>();
        String pathName = illuminatorPool.uploadFileTempPath + length + "_" + md5 + "\\";
        String splitFile[];
        if((splitFile = fileName.split("\\.")).length<=1){
            return  null;
        }
        String type = splitFile[splitFile.length-1];

        for (int i = 0; i < length; i++) {
            String afileName = pathName + i + "_" + md5+"."+type;
            File aFile = new File(afileName);
            if (!aFile.exists() || aFile.isDirectory()) {
                return null;
            }
            files.add(aFile);
        }

        File resultFile = new File(illuminatorPool.uploadFileSavePath + md5 + "_" + fileName);
        try (FileChannel resultFileChannel = new FileOutputStream(resultFile, true).getChannel()){
            for (File file:files) {
                try (FileChannel blk = new FileInputStream(file).getChannel()){
                    resultFileChannel.transferFrom(blk, resultFileChannel.size(), blk.size());
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        if (deleteFile(rootFile)) {
            return resultFile;
        }
        return null;
    }

    public static File mergeFilesByInputStream(String path, String fileName, String md5, int length) {

        File rootFile = new File(path);
        List<File> files = new ArrayList<>();
        String pathName = illuminatorPool.uploadFileTempPath + length + "_" + md5 + "\\";
        String splitFile[];
        if((splitFile = fileName.split("\\.")).length<=1){
            return  null;
        }
        String type = splitFile[splitFile.length-1];

        for (int i = 0; i < length; i++) {
            String afileName = pathName + i + "_" + md5+"."+type;
            File aFile = new File(afileName);
            if (!aFile.exists() || aFile.isDirectory()) {
                return null;
            }
            files.add(aFile);
        }

        if(rootFile.exists()&&rootFile.isDirectory()){
            File resultFile = new File(illuminatorPool.uploadFileSavePath+md5+"_"+fileName);
            try(BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(resultFile))) {
                int bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                for (File file:files) {
                    try(BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
                        int readcount;
                        while ((readcount = inputStream.read(buffer)) > 0) {
                            outputStream.write(buffer, 0, readcount);
                        }
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            if(deleteFile(rootFile)){
                return resultFile;
            }
        }
        return null;
    }

    //取文件前 10KB 来进行加密
    public static String md5File(InputStream inputStream)throws IOException{
        String res = null;
        res = DigestUtils.md5DigestAsHex(readFileByByte(inputStream,illuminatorPool.uploadFileMd5Size));
        inputStream.close();
        return res;
    }

    public static int checkSlice(String md5,int length){
        String path = illuminatorPool.uploadFileTempPath+length+"_"+md5;
        File fileRoot =  getDirectory(path);
        if(fileRoot==null){
            fileRoot = new File(path);
            return fileRoot.mkdir()?0:-1;
        }
        File[] files =fileRoot.listFiles();
        if(files==null){
            return 0;
        }
        return files.length;
    }


//    /** Extend Tools **/
//    public static com.genius.app.bean.File createIlluminatorFile(com.genius.app.bean.File iII_File,String FileId,String create_Date,String username,String fileName,File file){
//        iII_File.setFileUserId(username);
//        iII_File.setFileCreateDate(create_Date);
//        iII_File.setFileId(FileId);
//        iII_File.setFileName(fileName);
//        iII_File.setFilePath(file.getAbsolutePath());
//        iII_File.setFileType(getFileType(file));
//        iII_File.setFileSize(Long.toString(file.length()));
//        return iII_File;
//    }

    public static void test(String a){
        System.out.println(a);;
    }


}
